using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Config;
using Gameplay.PVE.Effect;
using Gameplay.PVE.Entity;
using Gameplay.PVE.Skill;
using Gameplay.PVE.Utils;
using UnityEditor;
using UnityEngine;
using Yoozoo.Libs;
using Yoozoo.Managers;

namespace Gameplay.PVE
{
    public enum EElementExistType
    {
        Coexist = 0,
        Cover = 1,
        Filter = 2,
        Compare = 3,
        CoexistAndRefresh = 4,
    }
    public class ElementBase : IClass
    {
        public PveSkillElementConfig config;
        protected UnitBase target;//目标
        protected UnitBase source;//来源
        protected Vector3 bulletPosition;
        protected float rigidBreak;
        public SkillBase skill;

        public bool IsFree
        {
            set
            {
                if (value)
                {
                    BattleLog.UnitLog(target,"FreeElement "+id);
                }
                
                m_isFree = value;
            }
            get
            {
                return m_isFree;
            }
        }
        private bool m_isFree;
        public bool IsCrit;
        protected float endTime;
        private List<ElementBase> subElements = new List<ElementBase>();
        public int plusTimes;
        public int id;
        
        private GameObject durationEffect;

        public bool isSkillAdditive;
        
        void IClass.OnReset()
        {
            destroyTriggerType = 0;
            destroyTriggerCount = 0;
            m_isFree = false;
            subElements.Clear();
            HideDurationEffect();
        }

        public float GetEndTime()
        {
            return endTime;
        }
        
        /// <summary>
        /// 执行
        /// </summary>
        public virtual void Execute()
        {
            if (PveManager.Instance.rpgFinish)
            {
                return;
            }
            if (!target.Data.isDead)
            {
                ShowFlyText();
                ShowEffect();
                ShowDurationEffect();
                CheckNeedShowHitMotion();
                CheckNeedShake();
                CheckNeedModelShake();
            }
            
            CheckNeedAddToSpecialBuff();
            var arg = ClassManager.Get<AddElementSuccessArg>();
            arg.element = this;
            target.Transmit(ETransmitType.AddElementSuccess,arg);
            ClassManager.Free(arg);
        }
        
        /// <summary>
        /// 每帧更新
        /// </summary>
        public virtual void Update()
        {
            UpdateLifeTime();
        }
        
        /// <summary>
        /// 设置目标
        /// </summary>
        public virtual void SetTarget(UnitBase target,UnitBase source)
        {
            this.target = target;
            this.source = source;
        }

        public virtual void SetSourceSkill(SkillBase skill)
        {
            this.skill = skill;
        }
        
        public virtual void SetRigidBreak(float rigidBreak)
        {
            this.rigidBreak = rigidBreak;
        }


        public void AddSubElements(ElementBase element)
        {
            if (element != null)
            {
                subElements.Add(element);
            }
        }
        
        /// <summary>
        /// 解析元素内容
        /// </summary>
        public virtual void Parse(PveSkillElementConfig config,bool isCrit)
        {
            IsCrit = isCrit;
            IsFree = false;
            this.config = config;
            float lastTime = GetValue("LastTime") / 1000f;
            if (lastTime >= 0)
            {
                endTime = lastTime + TimeManager.logicTime;
            }
            else
            {
                endTime = 0;
            }

            destroyTriggerType = GetValue("DestroyType");
            destroyTriggerCount = GetValue("DestroyParam");
            triggerCount = 0;
        }
        
        public void RefreshTime()
        {
            IsFree = false;
            float lastTime = GetValue("LastTime") / 1000f;
            if (lastTime >= 0)
            {
                endTime = lastTime + TimeManager.logicTime;
            }
            else
            {
                endTime = 0;
            }
        }

        /// <summary>
        /// 飘字
        /// </summary>
        protected virtual void ShowFlyText()
        {
            if (!string.IsNullOrEmpty(config.fly_text))
            {
                PveFlyTextManager.Instance.ShowFlyTextElement(PveUtils.GetLangText(config.fly_text),
                    target.Data.GetHudFlyTextPosition(),target.Data.id,source.Data.team,skill);
            }
        }

        /// <summary>
        /// 播放特效
        /// </summary>
        protected virtual void ShowEffect()
        {
            if (config.effect != 0)
            {
                PveEffectManager.Instance.PlayEffect(config.effect,target.Data.position,target.Data.forward,5,1,target.gameObject.transform);
            }
        }

        protected virtual void ShowDurationEffect()
        {
            if (config.duration_effect != 0)
            {
                durationEffect = PveEffectManager.Instance.PlayEffect(config.duration_effect,target);
            }
        }

        protected virtual void HideDurationEffect()
        {
            if (config != null && config.duration_effect != 0 && durationEffect != null)
            {
                PveResourceManager.RecoverResource(durationEffect,PveResourceManager.EPveResType.SkillEffect,config.duration_effect);
                durationEffect = null;
            }
        }

        public virtual void Pause()
        {
            if (durationEffect != null)
            {
                var controller = durationEffect.GetComponent<PveEffectController>();
                if (controller != null)
                {
                    controller.Pause();
                }
            }
        }

        public virtual void Resume()
        {
            if (durationEffect != null)
            {
                var controller = durationEffect.GetComponent<PveEffectController>();
                if (controller != null)
                {
                    controller.Resume();
                }
            }
        }
        
        /// <summary>
        /// 是否播放受击动作
        /// </summary>
        protected virtual void CheckNeedShowHitMotion()
        {
            /*if (config.hitMotion == 1)
            {
                target.Transmit(ETransmitType.PlayHitMotion);
            }*/
        }
        
        /// <summary>
        /// 是否震动
        /// </summary>
        protected virtual void CheckNeedShake()
        {
            /*if (config.shake == 1)
            {
                PveCameraManager.Instance.Shake(PveGlobalVlues.shakeTime,PveGlobalVlues.shakeRange,PveGlobalVlues.shakeInterval);
            }*/
        }

        protected virtual void CheckNeedModelShake()
        {
            if (config.model_shake_duration > 0)
            {
                var arg = ClassManager.Get<ModelShakeArg>();
                arg.model_shake_intensity = config.model_shake_intensity;
                arg.model_shake_rate = config.model_shake_rate;
                arg.model_shake_duration = config.model_shake_duration;
                target.Transmit(ETransmitType.PlayModelShake,arg);
                ClassManager.Free(arg);
            }
        }
        
        /// <summary>
        /// 销毁
        /// </summary>
        public virtual void Free()
        {
            for (int i = 0; i < subElements.Count; i++)
            {
                subElements[i].IsFree = true;
            }
            subElements.Clear();
            CheckNeedRemoveFromSpecialBuff();
            CheckNeedDoFreeAction();
            HideDurationEffect();
        }
        
        /// <summary>
        /// 更新生命周期
        /// </summary>
        public void UpdateLifeTime()
        {
            if (endTime > 0 && endTime <= TimeManager.logicTime)
            {
                IsFree = true;
            }
        }

        /// <summary>
        /// 检查是否需要加入特殊buff列表
        /// </summary>
        private void CheckNeedAddToSpecialBuff()
        {
            if (config.buff_type != 0)
            {
                List<ElementBase> elements = null;
                if (!target.Data.specialBuffs.TryGetValue(config.buff_type, out elements))
                {
                    elements = new List<ElementBase>();
                    target.Data.specialBuffs.Add(config.buff_type,elements);
                }
                elements.Add(this);
            }
        }

        private void CheckNeedDoFreeAction()
        {
            var freeAction = GetValue("FreeAction");
            if (freeAction == 1)
            {
                target.Transmit(ETransmitType.RecoverSkillInitiative);
            }
            else if (freeAction == 2)
            {
                target.Transmit(ETransmitType.RecoverSkillAuto);
            }
        }
        
        /// <summary>
        /// 检查是否需要移出特殊buff列表
        /// </summary>
        private void CheckNeedRemoveFromSpecialBuff()
        {
            if (config.buff_type != 0)
            {
                List<ElementBase> elements = null;
                if (target.Data.specialBuffs.TryGetValue(config.buff_type, out elements))
                {
                    for (int i = 0; i < elements.Count; i++)
                    {
                        if (elements[i] == this)
                        {
                            elements.RemoveAt(i);
                            i--;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 检查合并状态
        /// </summary>
        public virtual EElementExistType GetExistType(PveSkillElementConfig newConfig)
        {
            if (config.buff_type == newConfig.buff_type)
            {
                return (EElementExistType) config.combine_type;
            }
            return EElementExistType.Coexist;
        }

        
        private int destroyTriggerType;
        private int destroyTriggerCount;
        private int triggerCount;
        
        public void CheckNeedDestroyByTrigger(int triggerType)
        {
            if (triggerType == 0)
            {
                return;
            }
            if (destroyTriggerType == triggerType)
            {
                triggerCount++;
                if (triggerCount >= destroyTriggerCount)
                {
                    IsFree = true;
                }
            }
        }
        
        protected int GetValue(string key)
        {
            if (config.element_param.TryGetValue(key, out int value))
            {
                return value;
            }
            return 0;
        }

        public void SetBulletPosition(Vector3 position)
        {
            bulletPosition = position;
        }
    }
}